/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * \file
 * \brief Linux implementation of serial driver
 * \author Antti Maula <antti.maula@tkk.fi>
 * This header contains the class declaration for the Linux serial driver abstraction.
 */
#ifndef _SERIALSTD_LINUX_HPP_
#define _SERIALSTD_LINUX_HPP_

#include <termios.h>
#include <unistd.h>
#include <string>
#include "ASRoboBus.hpp"

/** Linux Serial driver interface.
 * This class is a simplified interface for Linux Serial driver. It's intended
 * to be matching to the Serial driver interface on windows, so we can use
 * the same code on both OSses.
 */
class CSerialStd : public CASRoboBus
{
public:
  /**
   * Advanced constructor
   *
   */
  CSerialStd();
 
 
  /**
   * Destructor.
   */
  virtual ~CSerialStd();


  /**
   * Derived function implementing the real opening of the device.
   *
   * @return                KBusStatusOK on ok, KBusStatusError on error.
   */
  EBusStatus Open(void);


  /**
   * Reads data from serial port. The read only reads as much data as is available.
   *
   * @param buffer          Buffer to read data to, must be atleast 'readb' bytes.
   * @param buffer_size     Storage available
   * @return                Negative on error, otherwise the number of bytes
   *                        stored on the 'buffer'
   */
  int Read(unsigned char *buffer, int buffer_size);


  /**
   * Writes data to serial port. Does not guarantee that the whole block
   * is sent.
   *
   * @param buffer          Buffer to write data from. Must be atleast
   *                        'buffer_size' bytes long.
   * @param buffer_size     Lenght of the data to write.
   * @return                Negative on error, otherwise number of bytes
   *                        really sent
   */
  int Write(const unsigned char *buffer, int buffer_size);


  /**
   * WaitToRead, matches select(). See definition from 'bus.hpp'
   *
   */
  EBusStatus WaitToRead(const int aTimeout_ms = -1);


  /**
   * WaitToWrite, matches select(). See definition from 'bus.hpp'
   *
   */
  EBusStatus WaitToWrite(const int aTimeout_ms = -1);


  /**
   * Closes serial device (Frees it for others)
   *
   * @return                KBusStatusOK on ok, KBusStatusError on error.
   */
  EBusStatus Close(void);


  /**
   * Flushes serial buffers == Clears incoming and outgoing data buffers.
   *
   * @return         Zero on success, negative value on error.
   */
  int Flush(void);

  
  EBusStatus SetPort(const std::string aPortName, int speed_bps) {
    iPortname = aPortName;
    iPortspeed = speed_bps;
    return KBusStatusOK;
  }


private:
  CSerialStd(const CSerialStd &) :
    CASRoboBus(),
    iIsOpen(),
    iPortname(),
    iPortspeed(0),
    iPortfd(0),
    iOldPortSet(NULL),
    iNewPortSet(NULL) {}
  CSerialStd& operator=(const CSerialStd &) { return *this; }

  bool iIsOpen;
  std::string iPortname;
  int iPortspeed;

  int iPortfd;

  struct termios *iOldPortSet;
  struct termios *iNewPortSet;
};

#endif //SERIALSTD












